package com.ruoyi.framework.webSocket;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.Chats;
import com.ruoyi.system.domain.Messages;
import com.ruoyi.system.mapper.ChatsMapper;
import com.ruoyi.system.mapper.MessagesMapper;
import org.springframework.context.ApplicationContext;
import com.ruoyi.system.mapper.SysUserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@ServerEndpoint("/websocket/{userId}/{type}")
public class WebSocketServer {

    private static ChatsMapper chatsMapper;
    private static MessagesMapper messagesMapper;
    private static SysUserMapper userMapper;
    @Autowired
    private ApplicationContext applicationContext;

    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);

    // 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    // concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    /**
     * 线程安全list，用来存放 在线客户端账号
     */
    public static List<String> userList = new CopyOnWriteArrayList<>();

    @PostConstruct
    public void init() {
        // 确保WebSocket服务启动时获取Spring的ApplicationContext
        chatsMapper = applicationContext.getBean(ChatsMapper.class);
        messagesMapper = applicationContext.getBean(MessagesMapper.class);
        userMapper = applicationContext.getBean(SysUserMapper.class);
    }

    /**
     * 连接成功
     * 
     * @param session
     * @param userId
     * @param type
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId,
            @PathParam(value = "type") String type) {
        log.debug("WebSocket连接成功，用户ID: " + userId);
        sessionPools.put(userId, session);
        if (!userList.contains(userId)) {
            addOnlineCount();
            userList.add(userId);
        }
        // Chats chats = new Chats();
        // List<Chats> list = chatsService.selectChatsList(chats);
        // log.debug("当前在线人数: " + onlineNum);
        // log.debug("当前在线用户: " + userList);
        List<Chats> list = getChatsList(userId, type);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            session.getBasicRemote().sendText(objectMapper.writeValueAsString(list));
        } catch (Exception e) {
            log.error("发送用户信息失败: " + e.getMessage(), e);
        }
    }

    public List<Chats> getChatsList(String userId, String type) {
        if (chatsMapper == null) {
            chatsMapper = applicationContext.getBean(ChatsMapper.class);
        }
        if (messagesMapper == null) {
            messagesMapper = applicationContext.getBean(MessagesMapper.class);
        }
        if (userMapper == null) {
            userMapper = applicationContext.getBean(SysUserMapper.class);
        }
        Chats chats = new Chats();

        if (type.equals("1")) {
            chats.setUser1Id(Long.parseLong(userId));
        } else {
            chats.setUser2Id(Long.parseLong(userId));
        }

        List<Chats> list = chatsMapper.selectChatsList(chats);

        for (Chats chats1 : list) {
            Long chatId = chats1.getChatId();
            Messages messages = new Messages();
            messages.setChatId(chatId);

            SysUser user = new SysUser();
            if (type.equals("1")) {
                user.setUserId(chats1.getUser2Id());
            } else {
                user.setUserId(chats1.getUser1Id());
            }
          

            List<SysUser> userData = userMapper.selectUserList(user);

            List<Messages> data = messagesMapper.selectMessagesList(messages);
            chats1.setMessages(data);
            chats1.setUser(userData.get(0));
        }
        return list;
    }

    /**
     * 关闭连接
     * 
     * @param userId
     */
    @OnClose
    public void onClose(@PathParam(value = "userId") String userId) {
        sessionPools.remove(userId);
        if (userList.contains(userId)) {
            userList.remove(userId);
            subOnlineCount();
        }
        log.debug(userId + "断开webSocket连接！当前人数为" + onlineNum);

    }

    /**
     * 消息监听
     *
     * @param message
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println(message);
        JSONObject jsonObject = JSONObject.parseObject(message);
        String name = jsonObject.getString("name");
        if (name.equals("message")) {
            String userId = jsonObject.getString("receiverId");
            Messages messages = new Messages();
            messages.setMessage(jsonObject); // 添加分号
            System.out.println(messages);
            if (messagesMapper == null) {
                messagesMapper = applicationContext.getBean(MessagesMapper.class);
            }
            messagesMapper.insertMessages(messages);
            sendToUser(userId, JSONObject.toJSONString(jsonObject));
        }
        if (name.equals("chat")) {
            if (chatsMapper == null) {
                chatsMapper = applicationContext.getBean(ChatsMapper.class);
            }
            Chats chat = new Chats();
            Long user1Id = jsonObject.getLong("user1Id");
            Long user2Id = jsonObject.getLong("user2Id");
            Date createdAt = jsonObject.getDate("createdAt");
            chat.setUser1Id(user1Id);
            chat.setUser2Id(user2Id);
            chat.setCreatedAt(createdAt);
            chatsMapper.insertChats(chat);
            sendChat(jsonObject.getString("user1Id"), jsonObject.getString("user2Id"));
        }
    }

    /**
     * 连接错误
     * 
     * @param session
     * @param throwable
     * @throws IOException
     */
    @OnError
    public void onError(Session session, Throwable throwable) throws IOException {
        System.out.println(throwable);
        log.error("websocket连接错误！", throwable);
        throwable.printStackTrace();
    }

    /**
     * 发送消息
     */
    public void sendMessage(Session session, String message) throws IOException, EncodeException {
        if (session != null) {
            synchronized (session) {
                session.getBasicRemote().sendText(message);
            }
        }
    }

    public void sendChat(String user1Id, String user2Id) {
        Session session1 = sessionPools.get(user1Id);
        Session session2 = sessionPools.get(user2Id);
        List<Chats> list1 = getChatsList(user1Id, "1");
        List<Chats> list2 = getChatsList(user2Id, "2");
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            session1.getBasicRemote().sendText(objectMapper.writeValueAsString(list1));
            ObjectMapper objectMapper1 = new ObjectMapper();
            session2.getBasicRemote().sendText(objectMapper1.writeValueAsString(list2));
        } catch (Exception e) {
            log.error("发送用户信息失败: " + e.getMessage(), e);
        }
     
    }

    /**
     * 给指定用户发送信息
     */
    public void sendToUser(String userId, String message) {
        Session session = sessionPools.get(userId);
        try {
            if (session != null) {
                sendMessage(session, message);
            } else {
                log.debug("推送用户不在线");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();

    }
}